package com.ticket;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class BuyTicket{
    private static Connection connection;
    private static PreparedStatement preparedStatement;
    private static ResultSet resultSet;
    private static Scanner scanner = new Scanner(System.in);

    // 加载数据库配置并建立连接
    private static void Conn() {
        try {
            connection = DBUtils.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 关闭数据库连接和相关资源
    private static void closeRes() {
        try {
            DBUtils.close(resultSet, preparedStatement, connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void buy() {
        while (true) {
            try {
                System.out.println("请输入1开始用演唱会id进行购票" + "\t" + "请输入2根据演出人员姓名进行购票" + "\t" + "输入-1返回上一级菜单");
                int i = scanner.nextInt();
                if (i == 1) {
                    buyTicket();
                } else if (i == 2) {
                    buyTicketByName();
                } else if (i == -1) {
                    break;
                } else {
                    System.out.println("输入错误，请重新输入");
                }
            } catch (Exception e) {
                System.out.println("输入格式错误，请重新输入");
                scanner = new Scanner(System.in);
            }
        }
    }

    // 购票方法（通过ID购票）
    public static boolean buyTicket() {
        try {
            int id = UserLogin.ID;
            System.out.println("请输入要购买的票的id:");
            while (!scanner.hasNextInt()) {
                System.out.println("输入格式错误，请重新输入!");
                scanner.next();
            }

            int concertId = scanner.nextInt();

            Conn();
            // 查询用户余额
            double userBalance = getUserBalance(id);
            if (userBalance == -1) {
                System.out.println("获取用户余额失败，请稍后重试。");
                return false;
            }

            // 查询演唱会门票价格和剩余票数
            double ticketPrice = getTicketPrice(concertId);
            int availableTickets = getAvailableTickets(concertId);
            if (ticketPrice == -1 || availableTickets == -1) {
                System.out.println("获取演唱会门票信息失败，请稍后重试。");
                return false;
            }

            System.out.print("请输入要购买的门票数量：");
            while (!scanner.hasNextInt()) {
                System.out.println("输入格式错误，请重新输入!");
                scanner.next();
            }
            int count = scanner.nextInt();

            double cost = ticketPrice * count;
            if (userBalance >= cost && availableTickets >= count) {
                // 更新用户余额
                updateUserBalance(id, userBalance - cost);

                // 更新门票剩余票数
                updateTicketAvailability(concertId, availableTickets - count);

                // 获取用户姓名
                String userName = getUserNameById(id);
                // 获取演唱会名称
                String concertName = getConcertName(concertId);
                // 获取演唱会时间
                String concertTime = getConcertTime(concertId);
                // 获取演唱会地点
                String concertPlace = getConcertPlace(concertId);

                // 将购票信息插入到buyticket表中
                insertPurchaseRecord(id, userName, concertName, concertTime, concertPlace, count);
                showPurchaseRecords(id);
                System.out.println("购票成功！");

                return true;
            } else {
                if (userBalance < cost) {
                    System.out.println("余额不足，无法购票，请充值后再试！");
                } else {
                    System.out.println("该演唱会门票剩余票数不足，无法购买这么多票！");
                }
            }

            closeRes();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    // 购票方法（通过演出人员姓名购票）
    private static boolean buyTicketByName() {
        try {
            int id = UserLogin.ID;
            System.out.println("请输入要购买的票的明星的名字:");
            String concertName = scanner.next();

            Conn();
            // 先判断输入的演唱会名称对应的演出是否存在
            if (!isConcertExistByName(concertName)) {
                System.out.println("没有查询到名为 " + concertName + " 的演出，请重新输入。");
                return false;
            }

            // 查询用户余额
            double userBalance = getUserBalance(id);
            if (userBalance == -1) {
                System.out.println("获取用户余额失败，请稍后重试。");
                return false;
            }

            // 查询演唱会的相关信息（门票价格、剩余票数以及各自的id、时间、地点等）
            List<Integer> concertIds = getConcertIdsByName(concertName);
            // 如果只有一场演出（名称唯一），直接进行购票操作
            if (concertIds.size() == 1) {
                int concertId = concertIds.get(0);
                double ticketPrice = getTicketPrice(concertId);
                int availableTickets = getAvailableTickets(concertId);

                System.out.print("请输入要购买的门票数量：");
                while (!scanner.hasNextInt()) {
                    System.out.println("输入格式错误，请重新输入!");
                    scanner.next();
                }
                int count = scanner.nextInt();

                double cost = ticketPrice * count;
                if (userBalance >= cost && availableTickets >= count) {
                    // 更新用户余额
                    updateUserBalance(id, userBalance - cost);

                    // 更新门票剩余票数
                    updateTicketAvailability(concertId, availableTickets - count);

                    // 获取用户姓名
                    String userName = getUserNameById(id);
                    // 获取演唱会名称
                    concertName = getConcertName(concertId);
                    // 获取演唱会时间
                    String concertTime = getConcertTime(concertId);
                    // 获取演唱会地点
                    String concertPlace = getConcertPlace(concertId);

                    // 将购票信息插入到buyticket表中
                    insertPurchaseRecord(id, userName, concertName, concertTime, concertPlace, count);
                    showPurchaseRecords(id);
                    System.out.println("购票成功！");

                    return true;
                } else {
                    if (userBalance < cost) {
                        System.out.println("余额不足，无法购票，请充值后再试！");
                    } else {
                        System.out.println("该演唱会门票剩余票数不足，无法购买这么多票！");
                    }
                }
            } else {
                // 如果有多场演出（有同名的不同场次），展示场次信息让用户选择场次ID后购票
                List<Double> ticketPrices = new ArrayList<>();
                List<Integer> availableTicketsList = new ArrayList<>();
                List<String> concertTimes = new ArrayList<>();
                List<String> concertPlaces = new ArrayList<>();
                for (int concertId : concertIds) {
                    double ticketPrice = getTicketPrice(concertId);
                    int availableTickets = getAvailableTickets(concertId);
                    String concertTime = getConcertTime(concertId);
                    String concertPlace = getConcertPlace(concertId);
                    ticketPrices.add(ticketPrice);
                    availableTicketsList.add(availableTickets);
                    concertTimes.add(concertTime);
                    concertPlaces.add(concertPlace);
                }

                // 展示所有演唱会场次信息让用户选择
                System.out.println("以下是名为 " + concertName + " 的演唱会场次信息，请输入要购买场次的id：");
                System.out.println("ID\t时间\t地点\t票价\t剩余票数");
                for (int i = 0; i < concertIds.size(); i++) {
                    System.out.println(concertIds.get(i) + "\t" + concertTimes.get(i) + "\t" + concertPlaces.get(i)
                            + "\t" + ticketPrices.get(i) + "\t" + availableTicketsList.get(i));
                }

                // 获取用户输入的演唱会id来选择场次
                while (true) {
                    System.out.println("请输入要购买场次的id：");
                    if (!scanner.hasNextInt()) {
                        System.out.println("输入格式错误，请重新输入!");
                        scanner.next();
                        continue;
                    }
                    int selectedConcertId = scanner.nextInt();
                    if (concertIds.contains(selectedConcertId)) {
                        int index = concertIds.indexOf(selectedConcertId);
                        double ticketPrice = ticketPrices.get(index);
                        int availableTickets = availableTicketsList.get(index);

                        System.out.print("请输入要购买的门票数量：");
                        while (!scanner.hasNextInt()) {
                            System.out.println("输入格式错误，请重新输入!");
                            scanner.next();
                        }
                        int count = scanner.nextInt();

                        double cost = ticketPrice * count;
                        if (userBalance >= cost && availableTickets >= count) {
                            // 更新用户余额
                            updateUserBalance(id, userBalance - cost);

                            // 更新门票剩余票数
                            updateTicketAvailability(selectedConcertId, availableTickets - count);

                            // 获取用户姓名
                            String userName = getUserNameById(id);
                            // 获取演唱会名称
                            concertName = getConcertName(selectedConcertId);
                            // 获取演唱会时间
                            String concertTime = concertTimes.get(index);
                            // 获取演唱会地点
                            String concertPlace = concertPlaces.get(index);

                            // 将购票信息插入到buyticket表中
                            insertPurchaseRecord(id, userName, concertName, concertTime, concertPlace, count);
                            showPurchaseRecords(id);
                            System.out.println("购票成功！");

                            return true;
                        } else {
                            if (userBalance < cost) {
                                System.out.println("余额不足，无法购票，请充值后再试！");
                            } else {
                                System.out.println("该演唱会门票剩余票数不足，无法购买这么多票！");
                            }
                        }
                        break;
                    } else {
                        System.out.println("输入的id无效，请重新输入。");
                    }
                }
            }

            closeRes();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    // 获取用户余额方法
    private static double getUserBalance(int id) throws SQLException {
        String sqlUserBalance = "select money from user where id =?";
        preparedStatement = connection.prepareStatement(sqlUserBalance);
        preparedStatement.setInt(1, id);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            return resultSet.getDouble("money");
        } else {
            System.out.println("未找到用户信息，请稍后重试！");
            return -1;
        }
    }

    // 获取指定演唱会的门票价格方法
    private static double getTicketPrice(int concertId) throws SQLException {
        String sqlTicketPrice = "select price  from concert where id =?";
        preparedStatement = connection.prepareStatement(sqlTicketPrice);
        preparedStatement.setInt(1, concertId);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            return resultSet.getDouble("price");
        } else {
            System.out.println("未找到该演唱会的票价信息，请稍后重试！");
            return -1;
        }
    }

    // 获取指定演唱会的剩余票数方法
    private static int getAvailableTickets(int concertId) throws SQLException {
        String sqlAvailableTickets = "select number from concert where id =?";
        preparedStatement = connection.prepareStatement(sqlAvailableTickets);
        preparedStatement.setInt(1, concertId);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            return resultSet.getInt("number");
        } else {
            System.out.println("未找到该演唱会的剩余票数信息，请稍后重试！");
            return -1;
        }
    }

    // 更新用户余额方法
    private static void updateUserBalance(int id, double newBalance) throws SQLException {
        String sqlUpdateUserBalance = "update user set money =? where id =?";
        preparedStatement = connection.prepareStatement(sqlUpdateUserBalance);
        preparedStatement.setDouble(1, newBalance);
        preparedStatement.setInt(2, id);
        preparedStatement.executeUpdate();
    }

    // 更新门票剩余票数方法
    private static void updateTicketAvailability(int concertId, int newAvailableTickets) throws SQLException {
        String sqlUpdateTicketAvailability = "update concert set number =? where id =?";
        preparedStatement = connection.prepareStatement(sqlUpdateTicketAvailability);
        preparedStatement.setInt(1, newAvailableTickets);
        preparedStatement.setInt(2, concertId);
        preparedStatement.executeUpdate();
    }

    // 根据用户id获取用户姓名的方法
    private static String getUserNameById(int id) throws SQLException {
        String sqlUserName = "select username from user where id =?";
        preparedStatement = connection.prepareStatement(sqlUserName);
        preparedStatement.setInt(1, id);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            return resultSet.getString("username");
        }

        return null;
    }

    // 根据演唱会id获取演唱会名称的方法
    private static String getConcertName(int concertId) throws SQLException {
        String sqlConcertName = "select name from concert where id =?";
        preparedStatement = connection.prepareStatement(sqlConcertName);
        preparedStatement.setInt(1, concertId);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            return resultSet.getString("name");
        }

        return null;
    }

    // 根据演唱会id获取演唱会时间的方法
    private static String getConcertTime(int concertId) throws SQLException {
        String sqlConcertTime = "select date from concert where id =?";
        preparedStatement = connection.prepareStatement(sqlConcertTime);
        preparedStatement.setInt(1, concertId);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            return resultSet.getString("date");
        }

        return null;
    }

    // 根据演唱会id获取演唱会地点的方法
    private static String getConcertPlace(int concertId) throws SQLException {
        String sqlConcertPlace = "select address from concert where id =?";
        preparedStatement = connection.prepareStatement(sqlConcertPlace);
        preparedStatement.setInt(1, concertId);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            return resultSet.getString("address");
        }

        return null;
    }

    private static List<Integer> getConcertIdsByName(String concertName) throws SQLException {
        List<Integer> concertIds = new ArrayList<>();
        String sqlGetIds = "select id from concert where name =?";
        preparedStatement = connection.prepareStatement(sqlGetIds);
        preparedStatement.setString(1, concertName);
        resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            concertIds.add(resultSet.getInt("id"));
        }
        return concertIds;
    }

    private static boolean isConcertExistByName(String concertName) throws SQLException {
        String sqlCheckExist = "select count(*) as count from concert where name =?";
        preparedStatement = connection.prepareStatement(sqlCheckExist);
        preparedStatement.setString(1, concertName);
        resultSet = preparedStatement.executeQuery();
        if (resultSet.next()) {
            int count = resultSet.getInt("count");
            return count > 0;
        }
        return false;
    }

    // 将购票记录插入到buyticket表的方法
    private static void insertPurchaseRecord(int user_id, String username, String concert_name, String concert_time,
                                             String concert_place, int ticket_count) throws SQLException {
        String sqlInsertRecord = "insert into buyticket (user_id,username,concert_name, concert_time, concert_place, ticket_count) " +
                "values (?,?,?,?,?,?)";
        preparedStatement = connection.prepareStatement(sqlInsertRecord);
        preparedStatement.setInt(1, user_id);
        preparedStatement.setString(2, username);
        preparedStatement.setString(3, concert_name);
        preparedStatement.setString(4, concert_time);
        preparedStatement.setString(5, concert_place);
        preparedStatement.setInt(6, ticket_count);
        preparedStatement.executeUpdate();

    }

    //    展示购票记录
    private static void showPurchaseRecords(int id) throws SQLException {
        String sqlShowRecords = "select * from buyticket where user_id =?";
        preparedStatement = connection.prepareStatement(sqlShowRecords);
        preparedStatement.setInt(1, id);
        resultSet = preparedStatement.executeQuery();
        System.out.println("以下是您的购票记录信息：");
        Map<String, Integer> groupedRecords = new HashMap<>();
        while (resultSet.next()) {
            String username = resultSet.getString("username");
            String concertName = resultSet.getString("concert_name");
            String concertTime = resultSet.getString("concert_time");
            String concertPlace = resultSet.getString("concert_place");
            int ticketCount = resultSet.getInt("ticket_count");

            // 构造演出的唯一标识字符串
            String key = username + "_" + concertName + "_" + concertTime + "_" + concertPlace;
            if (groupedRecords.containsKey(key)) {
                // 如果该演出已存在记录，累加购票数量
                groupedRecords.put(key, groupedRecords.get(key) + ticketCount);
            } else {
                // 如果是新的演出记录，添加到Map中，初始购票数量为当前记录的数量
                groupedRecords.put(key, ticketCount);
            }
        }
        System.out.println("用户名\t演唱会名称\t演唱会时间\t演唱会地点\t购票数量");
        for (Map.Entry<String, Integer> entry : groupedRecords.entrySet()) {
            String[] parts = entry.getKey().split("_");
            String username = parts[0];
            String concertName = parts[1];
            String concertTime = parts[2];
            String concertPlace = parts[3];
            int ticketCount = entry.getValue();

            // 输出每条记录信息
            System.out.println(username + "\t" + "\t" + concertName + "\t" + "\t" + concertTime + "\t"
                    + concertPlace + "\t" + "\t" + "\t" + ticketCount);
        }
    }
}